<?php

namespace app\common\model\merchant;

use app\common\loader\ModelMerchant;
use app\common\model\BaseModel;
use think\db\exception\DbException;
use think\Exception;
use yiqiniu\extend\facade\Db;

/**
 * 商户积分订单
 * Class MerchantOrderPoint
 * @package app\model
 */
class MerchantOrderPointModel extends BaseModel
{
    //
    protected $name = 'merchant_order_point';


    // 设置字段信息
    protected $schema = [
        'id' => 'int',        // 序号
        'order_no' => 'string',        // 订单号
        'mer_id' => 'string',        // 商户编号
        'product_code' => 'string',        // 商品码
        'product_title' => 'string',        // 商品名称
        'product_num' => 'int',        // 兑换数量
        'sum_point' => 'int',        // 总积分
        'user_type' => 'int',        // 用户类型 1:导购  2:会员
        'user_id' => 'int',        // 用户编号
        'real_name' => 'string',        // 收货姓名
        'mobile' => 'string',        // 手机号码
        'address' => 'string',        // 地址
        'express_company' => 'string',        // 快递公司
        'express_no' => 'string',        // 快递单号
        'status' => 'int',        // 状态 0 未处理 1发货   8 已完成
        'op_user' => 'int',        // 操作人
        'create_at' => 'datetime',        // 创建时间
        'update_at' => 'datetime',        // 更新时间
    ];

    /**
     * 订单详情
     * @param array $where
     */
    public function orderInfo(array $where)
    {
        $data = $this->db()->where($where)
            ->field('order_no,product_code,product_title,product_num,sum_point,user_type,
            real_name,mobile,address,express_company,express_no,status,status as status_name,create_at,mer_id')
            ->withAttr([
                'status_name' => function ($v) {
                    $array = ['0' => '未处理', '1' => '已发货','2' => '发货中', '8' => '已完成'];
                    return $array[$v];
                }
            ])->find();
        if (!empty($data)){
            $data['pics'] = $this->db('merchant_product_point')->where(['mer_id' => $data['mer_id'],'code' => $data['product_code']])
                ->value('pics');
        }
        return $data;

    }


    /**
     * 生成订单
     * @return array|mixed|\think\facade\Db|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function orderSave($data)
    {

        $id = $this->db()->where(['product_code' => $data['product_code'], 'user_id' => $data['user_id']])
            ->where('status', '<', '1')
            ->value('id');
        if (!empty($id)) {
            return $this->db()->where('id', $id)->update($data);
        }
        return $this->db()->insert($data);
    }

    /**
     * 订单提醒
     * @param $user_id |用户id
     * @param $mer_id |商户id
     */
    public function orderRemind($user_id, $mer_id)
    {
        $data = $this->db()->where(['user_id' => $user_id, 'mer_id' => $mer_id])
            ->field('
            SUM(case when status=0 then 1 else 0 end) as pending_num,
            SUM(case when status=1 then 1 else 0 end) as wait_goods_num,
            SUM(case when status=2 then 1 else 0 end) as send_goods_num')
            ->find();
        if (empty($data['pending_num']) && empty($data['wait_goods_num']) && empty($data['send_goods_num'])){
            return  [
                'pending_num' => 0,
                'wait_goods_num' => 0,
                'send_goods_num' => 0,
            ];
        }
        return  $data;
    }

    /**
     * 订单取消删除
     * @param $user_id |用户id
     * @param $mer_id |商户id
     * @param $order_no |订单
     * @throws DbException
     */
    public function orderCancel($user_id, $mer_id, $order_no): int
    {
        if ($this->db()->where(['user_id' => $user_id, 'mer_id' => $mer_id, 'order_no' => $order_no])
                ->value('status') > ORDER_STATUS_PENDING) {
            throw  new Exception('订单已支付,无法取消删除', API_ERROR);
        }
        return $this->db()->where(['user_id' => $user_id, 'mer_id' => $mer_id, 'order_no' => $order_no])
            ->delete();
    }


    /**
     * 订单确认
     * @param $user_id |用户id
     * @param $mer_id |商户id
     * @param $order_no |订单
     * @throws DbException
     */
    public function orderFinish($user_id, $mer_id, $order_no): int
    {
        return $this->db()->where(['user_id' => $user_id, 'mer_id' => $mer_id, 'order_no' => $order_no])
            ->update(['status' => 8]);
    }


    /**
     * 订单提交扣减库存操作
     * @param $user_id |用户id
     * @param $order_no |订单
     * @param $product_code |商品code
     * @param $product_num |商品数量
     * @param $mer_id |商户号
     * @throws DbException
     * @throws Exception
     */
    public function orderSubmit($user_id, $order_no, $product_code, $product_num, $mer_id): void
    {
        $order_info = [
            'mer_id' => $mer_id,
            'product_code' => $product_code,
            'product_num' => $product_num,
        ];
        $res = $this->db()->where(['order_no' => $order_no, 'user_id' => $user_id])
            ->where('product_code', 'in', function ($query) use ($order_info) {
                $query->name('merchant_product_point')
                    ->where(['mer_id' => $order_info['mer_id'], 'code' => $order_info['product_code']])
                    ->where('stock_num', '>=', $order_info['product_num'])
                    ->field('code');
            })->update(['status' => 1]);
        if (!$res) {
            throw  new Exception('订单提交失败(商品库存不足)', API_ERROR);
        }
        $stock = ModelMerchant::MerchantProductPoint()->where(['code' => $order_info['product_code'], 'mer_id' => $order_info['mer_id']])
            ->update(null, ['stock_num' => Db::raw("stock_num-" . $order_info['product_num'])]);
        if (!$stock) {
            throw  new Exception('订单提交失败', API_ERROR);
        }
    }

    /**
     * 商户订单统计
     * @param array $where
     * @return array
     * @throws DbException
     */
    public function promoUsedOrderList(array $where = []): array
    {
        return $this->db()->where($where ?? [])
            ->group('mer_id')
            ->column('sum(case when status=8 and user_type=2 then sum_point else 0 end) as member_point,
                           sum(case when status=8 and user_type=1 then sum_point else 0 end) as salesman_point'
                ,'mer_id');
    }
}
